package com.lz.comm.net

import com.lz.comm.extension.GSON
import com.lz.library.BuildConfig
import kotlinx.coroutines.Dispatchers
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.converter.scalars.ScalarsConverterFactory
import java.net.Proxy
import java.util.concurrent.TimeUnit
import java.util.regex.Pattern

/**
 * 适用于url随时变动的http管理
 */
object HttpManager {

    /**
     * 默认超时时间
     */
    private const val DEF_MILL_TIMEOUT = 10L//校验是否合格服务器地址

    //URL匹配
    const val URL_REGEX = "((http|https)://([a-zA-Z0-9\\._-]+\\.[a-zA-Z]{2,6})|([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}))(:[0-9]{1,4})*/"

    //校验是否合格服务器地址
    private val pattern = Pattern.compile(URL_REGEX)

    //判断是否为有效的服务器地址
    fun isEffectiveServer(url: String): Boolean {
        return pattern.matcher(url).find()
    }

    var baseUrl: String? = null

    private val client: OkHttpClient

    private var retrofit: Retrofit? = null

    init {
        val builder = OkHttpClient.Builder()
            .proxy(Proxy.NO_PROXY)
            .connectTimeout(DEF_MILL_TIMEOUT, TimeUnit.SECONDS)
            .writeTimeout(DEF_MILL_TIMEOUT, TimeUnit.SECONDS)
            .readTimeout(DEF_MILL_TIMEOUT, TimeUnit.SECONDS)
        if (!BuildConfig.isRelease) {
            builder.addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
        }
        client = builder.build()
    }

    //确保URL是正确的地址
    fun modifyBaseUrl(url: String) {
        if (url == this.baseUrl) return
        this.baseUrl = url
        retrofit = if (retrofit != null) {
            retrofit!!.newBuilder().baseUrl(baseUrl!!).build()
        } else {
            Retrofit.Builder()
                .callFactory(client)
                .addConverterFactory(ScalarsConverterFactory.create()) //增加返回值泛型String类型的支持
                .addConverterFactory(GsonConverterFactory.create(GSON)) //增加返回值泛型Gson类型的支持
                //返回Flow<T>的支持一般使用同步在IO中执行
                .addCallAdapterFactory(FlowCallAdapterFactory.createSynchronous(Dispatchers.IO))
                .baseUrl(baseUrl!!)
                .build()
        }
    }

    fun clearBaseUrl() {
        this.baseUrl = null
        this.retrofit = null
    }

    //是否已经配置服务器
    fun hasInitServer(): Boolean = baseUrl != null && retrofit != null

    fun <T> getService(serviceClass: Class<T>): T? {
        if (retrofit == null) return null
        return retrofit!!.create(serviceClass)
    }
}